package com.tianji.learning.task;

import cn.hutool.core.collection.CollUtil;
import com.tianji.learning.Constants.LearningConstants;
import com.tianji.learning.Constants.RedisConstants;
import com.tianji.learning.domain.po.PointsBoard;
import com.tianji.learning.domain.po.PointsBoardSeason;
import com.tianji.learning.service.IPointsBoardSeasonService;
import com.tianji.learning.service.IPointsBoardService;
import com.tianji.learning.utils.TableInfoContext;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Set;

@Component
@RequiredArgsConstructor
@Slf4j
public class PointsBoardPersistentHandler {

    private final IPointsBoardSeasonService seasonService;
    private final StringRedisTemplate redisTemplate;

    private final IPointsBoardService pointsBoardService;

   // @Scheduled(cron = "0 0 3 1 * ?") // 每月1号，凌晨3点执行
    @XxlJob("createTableJob")
    public void createPointsBoardTableOfLastSeason(){
        // 1.获取上月时间
        LocalDateTime time = LocalDateTime.now().minusMonths(1);
        // 2.查询赛季id
        PointsBoardSeason season = seasonService.lambdaQuery().le(PointsBoardSeason::getBeginTime, time).ge(PointsBoardSeason::getEndTime, time).one();
        if (season == null) {
            // 赛季不存在
            return;
        }
        // 3.创建表
        pointsBoardService.createPointsBoardTableBySeason(season);
    }
    @XxlJob("savePointsBoard2DB")//每个月1号，凌晨4点执行
    public void savePointsBoard2DB(){
        //1.获取上个月时间
        LocalDateTime beforeOneMonth = LocalDateTime.now().minusMonths(1);
        //2.格式化日期数据为yyyyMMdd
        String format = beforeOneMonth.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        //3.查询上个月的榜单数据，得到上次赛季id
        PointsBoardSeason season = seasonService.lambdaQuery().le(PointsBoardSeason::getBeginTime, beforeOneMonth).ge(PointsBoardSeason::getEndTime, beforeOneMonth).one();
        //4.将表名前缀加赛季id拼接，得到表名，放到ThreadLocal中
        TableInfoContext.setInfo(LearningConstants.POINTS_BOARD_TABLE_PREFIX+season.getId());
        //5.利用key查询redis
        String key= RedisConstants.POINTS_KEY_PREFIX+format;
        Set<ZSetOperations.TypedTuple<String>> typedTuples = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, -1);
        if (CollUtil.isEmpty(typedTuples)){
            return;
        }
        Long count=1L;
        ArrayList<PointsBoard> list = new ArrayList<>(typedTuples.size());
        for (ZSetOperations.TypedTuple<String> tuple : typedTuples) {
            String userIdStr = tuple.getValue();
            PointsBoard board = new PointsBoard();
            Double score = tuple.getScore();
            if (score != null){
                board.setPoints(score.intValue());
            }
            if (userIdStr != null) {
                board.setUserId(Long.valueOf(userIdStr));
            }

            board.setId(count);
            count++;
            list.add(board);
        }
        //6.将上个月的redis数据持久化到db中
        pointsBoardService.saveBatch(list);
        //7.删除上个月的redis数据
        redisTemplate.delete(key);
        //8.删除动态表名
        TableInfoContext.remove();
    }
   /* @XxlJob("savePointsBoard3DB")//每个月1号，凌晨4点执行
    public void savePointsBoard3DB(){
        TableInfoContext.setInfo(LearningConstants.POINTS_BOARD_TABLE_PREFIX+"7");
        //5.利用key查询redis
        String key= RedisConstants.POINTS_KEY_PREFIX+"202304";
        Set<ZSetOperations.TypedTuple<String>> typedTuples = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, -1);
        if (CollUtil.isEmpty(typedTuples)){
            return;
        }
        ArrayList<PointsBoard> list = new ArrayList<>(typedTuples.size());
        for (ZSetOperations.TypedTuple<String> tuple : typedTuples) {
            String userIdStr = tuple.getValue();
            PointsBoard board = new PointsBoard();
            Double score = tuple.getScore();
            if (score != null){
                board.setPoints(score.intValue());
            }
            if (userIdStr != null) {
                board.setUserId(Long.valueOf(userIdStr));
            }
            list.add(board);
        }
        //6.将上个月的redis数据持久化到db中
        pointsBoardService.saveBatch(list);
        //7.删除上个月的redis数据
        redisTemplate.delete(key);
        //8.删除动态表名
        TableInfoContext.remove();
    }*/






















}
